Source code for hysop.backend.device.logical_device
# Copyright (c) HySoP 2011-2024
#
# This file is part of HySoP software.
# See "https://particle_methods.gricad-pages.univ-grenoble-alpes.fr/hysop-doc/"
# for further info.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from abc import ABCMeta, abstractmethod
from hysop.tools.henum import EnumFactory
from hysop.tools.htypes import to_tuple
from hysop.backend.device.device_info import device_info
from hysop.constants import DeviceType
[docs]
class UnknownDeviceAttribute:
def __str__(self):
return "unknown"
[docs]
class LogicalDevice(metaclass=ABCMeta):
def __init__(
self,
platform,
platform_handle,
device_id,
device_handle,
hardware_topo,
**kargs,
):
super().__init__(**kargs)
self._platform = platform
self._device_id = device_id
physical_devices = self._match_physical_devices(hardware_topo=hardware_topo)
physical_devices = to_tuple(physical_devices)
self._physical_devices = physical_devices
vendor = hardware_topo.pciids.find_vendor(self.vendor_id())
self._vendor_handle = vendor
self._device_handle = None
# identifying device without device_id is not easy for CPUs
# so we do not look for a device handle
if physical_devices is not None:
for pd in physical_devices:
if (self.type() == DeviceType.CPU) or (pd is None):
continue
device = vendor.find_device(pd.device_id())
self._device_handle = device
self._determine_performance_and_affinity(hardware_topo)
[docs]
def hardware_device_id(self):
if self._device_handle is not None:
return self._device_handle.id
else:
return None
[docs]
def hardware_device_id_str(self):
did = self.hardware_device_id()
if did is not None:
return f" [0x{did:04x}]"
else:
return ""
@property
def device_id(self):
return self._device_id
@property
def platform(self):
return self._platform
@property
def physical_devices(self):
return self._physical_devices
@abstractmethod
def _match_physical_devices(self, hardware_topo):
pass
@abstractmethod
def _determine_performance_and_affinity(self, hardware_topo):
pass
[docs]
@abstractmethod
def to_string(self, indent, increment):
pass
def __str__(self):
return self.to_string(indent=0, increment=2)
# DEVICE
[docs]
@abstractmethod
def name(self):
pass
[docs]
@abstractmethod
def type(self):
pass
[docs]
@abstractmethod
def vendor(self):
pass
[docs]
@abstractmethod
def vendor_id(self):
pass
[docs]
@abstractmethod
def max_clock_frequency(self):
pass
[docs]
@abstractmethod
def address_bits(self):
pass
[docs]
@abstractmethod
def little_endian(self):
pass
[docs]
@abstractmethod
def available(self):
pass
[docs]
@abstractmethod
def compiler_available(self):
pass
[docs]
@abstractmethod
def error_correction_support(self):
pass
# KERNEL
[docs]
@abstractmethod
def max_grid_dim(self):
pass
[docs]
@abstractmethod
def max_grid_size(self):
pass
[docs]
@abstractmethod
def max_block_dim(self):
pass
[docs]
@abstractmethod
def max_block_size(self):
pass
[docs]
@abstractmethod
def max_threads_per_block(self):
pass
[docs]
@abstractmethod
def simd_lane_size(self):
pass
[docs]
@abstractmethod
def max_constant_args(self):
pass
# MEMORY
[docs]
@abstractmethod
def global_mem_size(self):
pass
[docs]
@abstractmethod
def global_mem_cache_size(self):
pass
[docs]
@abstractmethod
def global_mem_cacheline_size(self):
pass
[docs]
@abstractmethod
def global_mem_cache_type(self):
pass
[docs]
@abstractmethod
def max_global_alloc_size(self):
pass
[docs]
@abstractmethod
def local_mem_size(self):
pass
[docs]
@abstractmethod
def local_mem_type(self):
pass
# DEVICE SPLITTING
[docs]
@abstractmethod
def has_device_partition_support(self):
pass
[docs]
@abstractmethod
def max_subdevices(self):
pass
# QUEUES
[docs]
@abstractmethod
def has_queue_priority_support(self):
pass
# FP SUPPORT
[docs]
@abstractmethod
def has_fp16(self):
pass
[docs]
@abstractmethod
def has_fp32(self):
pass
[docs]
@abstractmethod
def has_fp64(self):
pass
[docs]
@abstractmethod
def fp16_config(self):
pass
[docs]
@abstractmethod
def fp32_config(self):
pass
[docs]
@abstractmethod
def fp64_config(self):
pass
# IMAGES
[docs]
def has_image_support(self):
pass
[docs]
def max_image_args(self):
pass
[docs]
def max_read_image_args(self):
pass
[docs]
def max_write_image_args(self):
pass
[docs]
def max_samplers(self):
pass
[docs]
def has_1d_image_support(self):
pass
[docs]
def has_2d_image_support(self):
pass
[docs]
def has_3d_image_support(self):
pass
[docs]
def has_1d_image_write_support(self):
pass
[docs]
def has_2d_image_write_support(self):
pass
[docs]
def has_3d_image_write_support(self):
pass
[docs]
def has_1d_image_array_support(self):
pass
[docs]
def has_2d_array_image_support(self):
pass
[docs]
def max_1d_image_size(self):
pass
[docs]
def max_1d_image_array_size(self):
pass
[docs]
def max_2d_image_size(self):
pass
[docs]
def max_2d_image_array_size(self):
pass
[docs]
def max_3d_image_size(self):
pass
[docs]
def has_2d_image_from_buffer_support(self):
pass
[docs]
def has_2d_image_from_image_support(self):
pass
[docs]
def image_base_address_alignment(self):
pass
[docs]
def image_pitch_aligment(self):
pass
[docs]
def image_max_buffer_size(self):
pass
[docs]
def image_max_array_size(self):
pass
# ATOMICS
[docs]
@abstractmethod
def has_global_int32_atomics(self):
pass
[docs]
@abstractmethod
def has_global_int64_atomics(self):
pass
[docs]
@abstractmethod
def has_global_float32_atomics(self):
pass
[docs]
@abstractmethod
def has_global_float64_atomics(self):
pass
[docs]
@abstractmethod
def has_local_int32_atomics(self):
pass
[docs]
@abstractmethod
def has_local_int64_atomics(self):
pass
[docs]
@abstractmethod
def has_local_float32_atomics(self):
pass
[docs]
@abstractmethod
def has_local_float64_atomics(self):
pass
[docs]
@abstractmethod
def has_mixed_int32_atomics(self):
pass
[docs]
@abstractmethod
def has_mixed_int64_atomics(self):
pass
[docs]
@abstractmethod
def has_mixed_float32_atomics(self):
pass
[docs]
@abstractmethod
def has_mixed_float64_atomics(self):
pass
[docs]
@abstractmethod
def has_int32_hardware_atomic_counters(self):
pass
[docs]
@abstractmethod
def has_int64_hardware_atomic_counters(self):
pass
[docs]
@abstractmethod
def preferred_local_atomic_alignment(self):
pass
[docs]
@abstractmethod
def preferred_global_atomic_alignment(self):
pass
# PROFILING
[docs]
@abstractmethod
def has_profiling_support(self):
pass
[docs]
@abstractmethod
def profiling_time_resolution(self):
pass
# PRINTF
[docs]
@abstractmethod
def has_printf_support(self):
pass
[docs]
@abstractmethod
def printf_buffer_size(self):
pass
# GRAPHIC API SHARING
[docs]
@abstractmethod
def has_gl_sharing(self):
pass
[docs]
@abstractmethod
def has_gl_event_sharing(self):
pass
[docs]
@abstractmethod
def has_gl_msaa_sharing(self):
pass
[docs]
@abstractmethod
def has_dx9_sharing(self):
pass
[docs]
@abstractmethod
def has_dx10_sharing(self):
pass
[docs]
@abstractmethod
def has_dx11_sharing(self):
pass